package com.iatinspur.learn;


import com.iatinspur.pojo.MyPeople;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * 28集 讲解引用计数法
 *
 * -verbose:gc
 */
public class Learn_25_JVM {
    public static void main(String[] args) throws MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        myTest3();

    }


    private static void myTest1() {
        MyPeople p = new MyPeople();
        // p = null 这个对象就能被回收了
        p = null;
    }


    /**
     * 循环依赖 如何被回收
     *
     * 其实只要代码里面 没有办法去找到他们两个 就能回收
     *  找到一个 就能找到另一个 照样不能回收
     *
     *  如何判断堆上的对象是否能被回收
     *   1.引用计数法  下面的循环依赖 是不能适用循环依赖的
     *   2.可达性分析法
     *
     *
     *
     */
    private static void myTest2() {
       A a1 = new A();
       B b1 = new B();
       b1.a = a1;
       a1.b = b1;
       //  我们一直认为 这样才能回收
//       a1.b = null;
//       b1.a = null;
//       a1 = null;
//       b1 = null;

       // todo 其实 这样就能回收
        b1 = null;
        a1 = null;

    }


    /**
     *
     *  使用 -verbose:gc
     *                          清理前堆内存      清理后内存
     *  [Full GC (System.gc())  1066K    ->     1034K(623616K), 0.0020859 secs]
     *
     *  至少证明循环依赖  不是引用计数 这个是可达性分析法
     *  可达性 感觉就是 没有办法去找到他们两个 就能回收
     */
    private static void myTest3() {
        while(true){
            A a1 = new A();
            B b1 = new B();
            b1.a = a1;
            a1.b = b1;
            // todo 其实 这样就能回收
            b1 = null;
            a1 = null;
            System.gc();
        }
    }


}


class A{
    B b;
}

class B{
    A a;
}








